package hku.cs.lunuo.marker;

import hku.cs.constant.DirAndFileConstant;
import hku.cs.lunuo.LunuoPlugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class SuspMarker {
	public final static String MARKER_ID = LunuoPlugin.PLUGIN_ID
			+ ".suspicious";
	public final static String RANK = "rank";
	public final static String SUSPICIOUS = "suspicious";
	
	private IJavaProject javaProject;

	public SuspMarker(String strPrjName) {
		javaProject = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()
				.getProject(strPrjName));
	}

	public boolean deleteMarkers() {
		try {
			javaProject.getProject().deleteMarkers(MARKER_ID, false,
					IResource.DEPTH_INFINITE);
			return true;
		} catch (CoreException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	private class Location{
		int charstart;
		int charend;
		public Location(int charstart, int charend) {
			super();
			this.charstart = charstart;
			this.charend = charend;
		}
		
	}

	public void addMarkers(String testcaseDirName) {
		deleteMarkers();
		File susF = new File(testcaseDirName+
				DirAndFileConstant.RANK
						+ DirAndFileConstant.FILEEXTENTION);
		SAXBuilder sb = new SAXBuilder();
		try {
			Document xmlDoc = sb.build(susF);
			Element xmlRoot = (Element) xmlDoc.getRootElement();
			Iterator xmlStmtIt = xmlRoot.getChildren("statement").iterator();
			while(xmlStmtIt.hasNext()){
				Element xmlStmt = (Element)xmlStmtIt.next();
				Element xmlRank = xmlStmt.getChild("rank");		
				final String rank = xmlRank.getText();
				Element xmlSus = xmlStmt.getChild("suspiciousness");
				final String suspicious = xmlSus.getText();
				final String className = xmlStmt.getAttributeValue("class");
				final String line = xmlStmt.getAttributeValue("line");				
				final IResource jR = javaProject.findType(className).getResource();
				IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
					public void run(IProgressMonitor monitor) throws CoreException {
						File cF = jR.getLocation().toFile();
						Location loc = findLocation(cF, Integer.parseInt(line));
						IMarker marker = jR.createMarker(MARKER_ID);
						marker.setAttribute(RANK, rank);
						marker.setAttribute(SUSPICIOUS, suspicious);
						marker.setAttribute(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
//						marker.setAttribute(IMarker.LINE_NUMBER, line);
						marker.setAttribute(IMarker.LOCATION, line + " line");
						marker.setAttribute(IMarker.CHAR_START, new Integer(loc.charstart));
						marker.setAttribute(IMarker.CHAR_END, new Integer(loc.charend));
//						marker.setAttribute(IMarker.MESSAGE, "The suspicious line");
					}
				};
				jR.getWorkspace().run(runnable, null);
			}
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JavaModelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private Location findLocation(File cf, int line) {
		BufferedReader fr = null;
		try {
			fr = new BufferedReader(new FileReader(cf));
			int i = 1;
			int charstart = 0;
			int charend = 0;
			while(i < line){
				String s = fr.readLine();
				charstart+=s.length()+1;
				i++;
			}
			charend = charstart+ fr.readLine().length();
			return new Location(charstart, charend);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(fr != null)
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return null;
	}
}
